// src/scenarios/robotics.rs

//! 机器人应用场景
//! 支持工业机器人的语义转换和OPC UA模型构建

use crate::scenarios::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// 工业机器人场景
pub struct IndustrialRoboticsScenario {
    config: ScenarioConfig,
}

/// 机器人类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RobotType {
    /// 六轴机器人
    SixAxis,
    /// SCARA机器人
    SCARA,
    /// Delta机器人
    Delta,
    /// 协作机器人
    Collaborative,
    /// AGV/AMR
    AGV,
    /// 并联机器人
    Parallel,
}

/// 机器人运动模式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RobotMotionMode {
    /// 点到点运动
    PointToPoint,
    /// 直线运动
    Linear,
    /// 圆弧运动
    Circular,
    /// 关节运动
    Joint,
}

/// 控制模式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RobotControlMode {
    /// 手动模式
    Manual,
    /// 自动模式
    Automatic,
    /// 示教模式
    Teach,
    /// 远程模式
    Remote,
}

impl IndustrialRoboticsScenario {
    pub fn new() -> Self {
        Self {
            config: ScenarioConfig {
                name: Some("工业机器人语义转换场景".to_string()),
                description: Some("支持工业机器人数据的语义转换和OPC UA模型构建，包括六轴机器人、SCARA机器人、协作机器人等".to_string()),
                custom_rules: None,
                extensions: HashMap::new(),
            },
        }
    }

    pub fn new_with_config(config: ScenarioConfig) -> Self {
        Self { config }
    }
}

impl Scenario for IndustrialRoboticsScenario {
    fn name(&self) -> &'static str {
        "Industrial Robotics Semantic Conversion"
    }

    fn description(&self) -> &'static str {
        "工业机器人语义转换场景，支持各种工业机器人的语义转换和OPC UA模型构建"
    }

    fn industry(&self) -> &'static str {
        "Robotics"
    }

    fn get_transformation_rules(&self) -> ScenarioTransformationRules {
        let mut mappings = HashMap::new();

        mappings.insert("joint_position".to_string(), "JointAngle".to_string());
        mappings.insert("tcp_position".to_string(), "ToolCenterPointPosition".to_string());
        mappings.insert("tcp_orientation".to_string(), "ToolCenterPointOrientation".to_string());
        mappings.insert("payload".to_string(), "Load".to_string());
        mappings.insert("speed".to_string(), "Velocity".to_string());
        mappings.insert("acceleration".to_string(), "Acceleration".to_string());

        ScenarioTransformationRules {
            rule_name: "Industrial_Robotics_General".to_string(),
            data_source_mappings: mappings,
            unit_conversions: HashMap::new(),
            data_type_mappings: HashMap::new(),
            semantic_mappings: HashMap::new(),
            constraints: vec![],
        }
    }

    fn get_opcua_model_template(&self) -> ScenarioModelTemplate {
        ScenarioModelTemplate {
            template_name: "IndustrialRoboticsModel".to_string(),
            namespaces: vec![
                "http://opcfoundation.org/UA/".to_string(),
                "http://iso.org/15745-1/2003/ID".to_string(),
                "http://industryagent.com/robotics/".to_string(),
            ],
            object_types: vec![
                ObjectTypeTemplate {
                    type_name: "IndustrialRobotType".to_string(),
                    description: Some("工业机器人基础类型".to_string()),
                    parent_type: Some("BaseObjectType".to_string()),
                    properties: vec![
                        PropertyTemplate {
                            name: "RobotId".to_string(),
                            data_type: "String".to_string(),
                            description: Some("机器人唯一标识符".to_string()),
                            unit: None,
                            required: true,
                            default_value: None,
                        },
                        PropertyTemplate {
                            name: "RobotType".to_string(),
                            data_type: "RobotTypeEnum".to_string(),
                            description: Some("机器人类型".to_string()),
                            unit: None,
                            required: true,
                            default_value: None,
                        },
                        PropertyTemplate {
                            name: "ControlMode".to_string(),
                            data_type: "ControlModeEnum".to_string(),
                            description: Some("控制模式".to_string()),
                            unit: None,
                            required: true,
                            default_value: Some(serde_json::json!("Manual")),
                        },
                        PropertyTemplate {
                            name: "MotionMode".to_string(),
                            data_type: "MotionModeEnum".to_string(),
                            description: Some("运动模式".to_string()),
                            unit: None,
                            required: true,
                            default_value: Some(serde_json::json!("PointToPoint")),
                        },
                    ],
                    methods: vec![
                        MethodTemplate {
                            name: "MoveToPosition".to_string(),
                            description: Some("移动到指定位置".to_string()),
                            input_arguments: vec![
                                ArgumentTemplate {
                                    name: "TargetPosition".to_string(),
                                    data_type: "Position".to_string(),
                                    description: Some("目标位置".to_string()),
                                    unit: Some("m".to_string()),
                                },
                            ],
                            output_arguments: vec![
                                ArgumentTemplate {
                                    name: "Success".to_string(),
                                    data_type: "Boolean".to_string(),
                                    description: Some("操作是否成功".to_string()),
                                    unit: None,
                                },
                            ],
                        },
                        MethodTemplate {
                            name: "SetSpeed".to_string(),
                            description: Some("设置运行速度".to_string()),
                            input_arguments: vec![
                                ArgumentTemplate {
                                    name: "Speed".to_string(),
                                    data_type: "Double".to_string(),
                                    description: Some("速度值".to_string()),
                                    unit: Some("m/s".to_string()),
                                },
                            ],
                            output_arguments: vec![
                                ArgumentTemplate {
                                    name: "Success".to_string(),
                                    data_type: "Boolean".to_string(),
                                    description: Some("操作是否成功".to_string()),
                                    unit: None,
                                },
                            ],
                        },
                    ],
                },
            ],
            variable_types: vec![
                VariableTypeTemplate {
                    type_name: "JointPositionType".to_string(),
                    data_type: "Double".to_string(),
                    description: Some("关节位置类型".to_string()),
                    unit: Some("rad".to_string()),
                    min_value: Some(-std::f64::consts::PI),
                    max_value: Some(std::f64::consts::PI),
                },
            ],
            reference_types: vec![],
        }
    }

    fn get_sample_data(&self) -> Vec<ScenarioSampleData> {
        vec![
            ScenarioSampleData {
                data_id: "six_axis_robot_001".to_string(),
                data_source_type: "HuaweiCloudIoT".to_string(),
                raw_data: serde_json::json!({
                    "robot_id": "RB6-001",
                    "robot_name": "六轴机器人-001",
                    "robot_type": "SixAxis",
                    "control_mode": "Automatic",
                    "motion_mode": "Linear",
                    "joint_positions": [0.0, 45.0, -90.0, 0.0, 90.0, 0.0],
                    "tcp_position": {"x": 500.0, "y": 300.0, "z": 800.0},
                    "tcp_orientation": {"roll": 0.0, "pitch": 90.0, "yaw": 0.0},
                    "payload": 15.5,
                    "speed": 1.2,
                    "acceleration": 2.5,
                    "timestamp": "2024-01-15T10:30:00Z"
                }),
                expected_opcua: serde_json::json!({
                    "nodeId": "ns=3;i=1001",
                    "nodeClass": "Object",
                    "browseName": "RB6-001",
                    "typeDefinition": "ns=3;i=1000"
                }),
                description: Some("六轴工业机器人数据示例".to_string()),
                category: Some("ArticulatedRobot".to_string()),
            },
        ]
    }

    fn get_semantic_mappings(&self) -> HashMap<String, String> {
        let mut mappings = HashMap::new();
        mappings.insert("SixAxis".to_string(), "ArticulatedRobot".to_string());
        mappings.insert("SCARA".to_string(), "SelectiveComplianceAssemblyRobotArm".to_string());
        mappings.insert("Delta".to_string(), "ParallelRobot".to_string());
        mappings
    }
}